package com.jgzx.security.aspect;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.jgzx.common.ResultCode;
import com.jgzx.domain.LoginUser;
import com.jgzx.exception.BizException;
import com.jgzx.redis.login.LoginCache;
import com.jgzx.security.annotation.PreAuthorize;
import com.jgzx.security.service.TokenService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Collection;

/**
 * @author jackesy
 * @className: PreAuthorizeAspect
 * @description: 自定义权限实现
 * @create 2021/2/6 18:42
 **/
@Aspect
@Component
public class PreAuthorizeAspect {

    @Autowired
    private TokenService tokenService;

    /**
     * 所有权限标识
     */
    private static final String ALL_PERMISSION = "*:*:*";

    @Around("@annotation(com.jgzx.security.annotation.PreAuthorize)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
        if (annotation == null) {
            return point.proceed();
        }
        if (StrUtil.isNotEmpty(annotation.hasPermi())) {
            if (hasPermi(annotation.hasPermi())) {
                return point.proceed();
            }
            throw new BizException(ResultCode.UN_AUTHORIZED, "无权限请求该资源");
        }
        return point.proceed();
    }

    /**
     * 验证用户是否具备某权限
     *
     * @param permission 权限字符串
     * @return 用户是否具备某权限
     */
    public boolean hasPermi(String permission) {
        LoginUser loginUser = LoginCache.getLoginUser();
        if (ObjectUtil.isNull(loginUser)) {
            return false;
        }
        //超级管理员不验证权限
        if (loginUser.getAdmin_flag()) {
            return true;
        }
        if (CollUtil.isEmpty(loginUser.getPerms())) {
            return false;
        }
        return hasPermissions(loginUser.getPerms(), permission);
    }

    /**
     * 判断是否包含权限
     *
     * @param authorities 权限列表
     * @param permission  权限字符串
     * @return 用户是否具备某权限
     */
    private boolean hasPermissions(Collection<String> authorities, String permission) {
        return authorities.stream().filter(StringUtils::hasText)
                .anyMatch(x -> ALL_PERMISSION.equals(StrUtil.trim(x)) || StrUtil.trim(x).equals(StrUtil.trim(permission)));
    }

}
